﻿using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;
using Core.Caching;
using Core.Domain.Entities;
using Core.Helpers;
using Core.Identity.Common.Interfaces.Common.Interfaces;
using Core.Identity.Organizations.Caching;
using Core.Models;
using MediatR;
using Microsoft.EntityFrameworkCore;

namespace Core.Identity.Organizations.Features.Commands.Create;

public class CreateOrganizationCommand : ICacheInvalidatorRequest<Result<Guid>>
{
    /// <summary>
    /// 组织机构名称
    /// </summary>
    [Required(ErrorMessage = "名称是必填的")]
    public required string Name { get; set; }
    /// <summary>
    /// 组织机构编码
    /// </summary>
    [Required(ErrorMessage = "编码是必填的")]
    public required string Code { get; set; }
    /// <summary>
    /// 父级组织机构Id
    /// </summary>
    public Guid? ParentId { get; set; }

    /// <summary>
    /// 设置排序
    /// </summary>
    public int? Sort { get; set; }

    /// <summary>
    /// 设置描述
    /// </summary>
    public string? Description { get; set; }

    /// <summary>
    /// 设置启用/禁用
    /// </summary>
    public bool? Enabled { get; set; }

    [JsonIgnore]
    public string CacheKey => OrganizationsCacheKey.GetAllCacheKey;

    [JsonIgnore]
    public IEnumerable<string>? Tags => OrganizationsCacheKey.Tags;
}

public class CreateOrganizationCommandHandler(IIdentityDbContext dbContext) : IRequestHandler<CreateOrganizationCommand, Result<Guid>>
{

    public async Task<Result<Guid>> Handle(CreateOrganizationCommand request, CancellationToken cancellationToken)
    {
        var organization = await dbContext.Organizations
            .FirstOrDefaultAsync(x => x.Name == request.Name, cancellationToken);
        ExceptionHelper.ThrowIfNotNull(organization, "组织名称已存在");

        organization = await dbContext.Organizations
            .FirstOrDefaultAsync(x => x.Code == request.Code, cancellationToken);
        ExceptionHelper.ThrowIfNotNull(organization, "组织编码已被占用");

        if (request.ParentId != null)
        {
            organization = await dbContext.Organizations
            .FirstOrDefaultAsync(x => x.Id == request.ParentId, cancellationToken);
            ExceptionHelper.ThrowIfNull(organization, "父级组织不存在");
        }

        organization = Organization.Create(request.Name, request.Code, request.ParentId);
        organization.Sort = request.Sort;
        organization.Description = request.Description;
        organization.Enabled = request.Enabled ?? true;

        await dbContext.Organizations.AddAsync(organization);

        var result = await dbContext.SaveChangesAsync(cancellationToken) > 0;
        return await Result<Guid>.SucceedAsync(result, organization.Id, ["创建失败"]);
    }
}
